Skip to content

Command palette: unmount while closed and show a sidebar hint#1268

Merged
RhysSullivan merged 1 commit into
mainfrom
ux/command-palette
Jul 2, 2026
Merged

Command palette: unmount while closed and show a sidebar hint#1268
RhysSullivan merged 1 commit into
mainfrom
ux/command-palette

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Jul 2, 2026

Copy link
Copy Markdown
Owner

The closed command palette kept its content mounted, so Command Palette / Search for a command to run... leaked into every page's text and accessibility tree as the first thing a screen reader announces. There was also no visible hint the palette exists.

The palette content now unmounts while closed, and the sidebar footer gets a Commands row with the keyboard shortcut so the feature is discoverable.

Verified in the browser (page text no longer contains the palette copy while closed; the hint opens it). Typecheck is green.

Stacked on #1267.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown

Greptile Summary

Fixes an accessibility regression where the unmounted-but-open CommandPalette leaked its placeholder text into every page's DOM and screen-reader tree, and adds a discoverable sidebar hint for the feature.

  • CommandPalette now accepts open/onOpenChange as props; it returns null early when closed, fully unmounting the dialog content from the DOM.
  • Both shell variants (web and multiplayer) gain a commandPaletteOpen state and a "Commands / ⌘K" footer button in the sidebar that drives the palette open, with the mobile path also collapsing the sidebar first.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to unmounting dialog content when closed and adding a sidebar shortcut hint, with no effect on data flow or navigation logic.

The state lift is correct, hooks all fire before the early return so Rules of Hooks are satisfied, and the keyboard listener remains active via the effect regardless of open state. The only behavioral difference worth noting is that Radix's exit animation is now bypassed on close, but this is a UX polish concern and not a functional regression.

packages/react/src/components/command-palette.tsx — the early-return unmount pattern skips CommandDialog's closing animation.

Important Files Changed

Filename Overview
packages/react/src/components/command-palette.tsx Lifts open state out of the component, adds early if (!open) return null guard to unmount content, and re-wires the keydown effect with [onOpenChange, open] deps. Hard-unmount skips CommandDialog's exit animation.
packages/app/src/web/shell.tsx Adds commandPaletteOpen state, threads it into CommandPalette, and adds a Commands footer button with ⌘K label to SidebarContent. Mobile path also closes the sidebar before opening the palette.
packages/react/src/multiplayer/shell.tsx Mirrors the web shell changes: new CommandsButton component, commandPaletteOpen state, and onOpenCommands prop threaded to SidebarContent for both desktop and mobile.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant Sidebar as SidebarContent
    participant Shell as Shell (state owner)
    participant CP as CommandPalette

    Note over Shell: commandPaletteOpen = false
    Shell->>CP: "open=false → returns null (unmounted)"

    User->>Sidebar: clicks "Commands ⌘K"
    Sidebar->>Shell: onOpenCommands()
    Shell->>Shell: setCommandPaletteOpen(true)
    Shell->>CP: "open=true → mounts CommandDialog"

    User->>CP: presses Escape / selects item
    CP->>Shell: onOpenChange(false)
    Shell->>Shell: setCommandPaletteOpen(false)
    Shell->>CP: "open=false → returns null (unmounted)"

    Note over CP: Keydown listener stays active via useEffect (runs before early return)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant Sidebar as SidebarContent
    participant Shell as Shell (state owner)
    participant CP as CommandPalette

    Note over Shell: commandPaletteOpen = false
    Shell->>CP: "open=false → returns null (unmounted)"

    User->>Sidebar: clicks "Commands ⌘K"
    Sidebar->>Shell: onOpenCommands()
    Shell->>Shell: setCommandPaletteOpen(true)
    Shell->>CP: "open=true → mounts CommandDialog"

    User->>CP: presses Escape / selects item
    CP->>Shell: onOpenChange(false)
    Shell->>Shell: setCommandPaletteOpen(false)
    Shell->>CP: "open=false → returns null (unmounted)"

    Note over CP: Keydown listener stays active via useEffect (runs before early return)
Loading

Reviews (3): Last reviewed commit: "Unmount the command palette while closed" | Re-trigger Greptile

Comment on lines +225 to +226
<span>Commands</span>
<span className="font-mono text-[11px]">⌘K</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The ⌘K label is Mac-only. The keyboard handler in CommandPalette also matches Ctrl+K, so Windows/Linux users pressing Ctrl+K will open the palette but see a symbol that doesn't match their keyboard. A simple platform sniff (navigator.platform or UA Mac) at render time would let you show Ctrl+K on non-Mac.

Suggested change
<span>Commands</span>
<span className="font-mono text-[11px]">⌘K</span>
<span>Commands</span>
<span className="font-mono text-[11px]">
{typeof navigator !== "undefined" && /Mac/.test(navigator.platform) ? "⌘K" : "Ctrl+K"}
</span>

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Cloudflare preview

Torn down — the PR is closed.

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1268

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1268

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1268

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1268

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1268

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1268

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1268

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1268

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1268

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1268

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1268

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1268

executor

npm i https://pkg.pr.new/executor@1268

commit: fc199ee

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 3ab4cab Commit Preview URL

Branch Preview URL
Jul 02 2026, 08:35 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
executor-cloud 3ab4cab Jul 02 2026, 08:36 PM

@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch from 7230dd0 to ac34707 Compare July 2, 2026 17:52
@RhysSullivan RhysSullivan force-pushed the ux/command-palette branch 2 times, most recently from 98343cd to fc199ee Compare July 2, 2026 17:55
@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch from ac34707 to 9566a11 Compare July 2, 2026 17:55
@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch from 9566a11 to 9c567e5 Compare July 2, 2026 18:20
@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch 2 times, most recently from 26755fb to 51ed6e9 Compare July 2, 2026 18:21
@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch from 51ed6e9 to 7828740 Compare July 2, 2026 18:21
@RhysSullivan RhysSullivan force-pushed the ux/command-palette branch 2 times, most recently from 23b37ed to 334c26e Compare July 2, 2026 18:22
@RhysSullivan RhysSullivan force-pushed the ux/copy-and-naming-pass branch 2 times, most recently from 07590a7 to 97bacb8 Compare July 2, 2026 18:22
@RhysSullivan RhysSullivan changed the base branch from ux/copy-and-naming-pass to main July 2, 2026 18:22
@RhysSullivan RhysSullivan merged commit b0f36f3 into main Jul 2, 2026
17 of 23 checks passed
@RhysSullivan RhysSullivan deleted the ux/command-palette branch July 2, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant